package io.renren.modules.weixin.servlet;

import com.alibaba.fastjson.JSONObject;
import com.mysql.jdbc.util.BaseBugReport;
import io.renren.common.utils.*;
import io.renren.modules.weixin.config.WXConfig;
import io.renren.modules.weixin.handler.DispatcherEventHandler;
import io.renren.modules.weixin.handler.EventHandler;
import io.renren.modules.weixin.handler.MessageHandler;
import io.renren.modules.weixin.message.BaseReq;
import io.renren.modules.weixin.message.reqMsg.BaseReqMsg;
import io.renren.modules.weixin.message.responsemsg.BaseMsg;
import io.renren.modules.weixin.util.WeiXinUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.*;

@Component
public class WeixinServlet extends HttpServlet {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private WXConfig wxConfig;

    //处理微信事件handler列表
    private DispatcherEventHandler dispatcherEventHandler;
   //处理微信消息handler
    private Map<String,MessageHandler> messageHandleMap = new HashMap<>();


    private final String prifxReqMsgBean = "io.renren.modules.weixin.message.reqMsg.";


    @Override
    public void init(ServletConfig config) throws ServletException {
        wxConfig = (WXConfig)SpringContextUtils.getBean("wxConfig");
        String str = config.getInitParameter("msgHandlerClass");
        dispatcherEventHandler = new DispatcherEventHandler();
        //初始化消息处理handler
        Map<String,String> map = (Map)JSONObject.parse(str);
        map.forEach((String k, String v) ->{
            try {
                Class<MessageHandler> messageHandle = (Class<MessageHandler>) Class.forName(v);
                messageHandleMap.put(k,messageHandle.newInstance());

            } catch (Exception e) {
                logger.error("微信消息处理handler初始化失败,{}",map);
                e.printStackTrace();
                return;
            }
        });
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Dom4jHelper dom4jHelper = null;
        BaseMsg resutlMsg = null;
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter writer = resp.getWriter();
        String fromUserName = null;
        String toUserName = null;
        try {
            dom4jHelper = new Dom4jHelper(req.getInputStream());
            System.out.println(dom4jHelper.getAllElements());
            fromUserName = dom4jHelper.getElementValue("FromUserName");
            toUserName = dom4jHelper.getElementValue("ToUserName");
        } catch (DocumentException e) {
            logger.error("接入的微信消息转换xml失败",e);
            writer.write("");
            writer.flush();
            writer.close();
        }
        try{
            String msgType = dom4jHelper.getElementValue("MsgType");
            if(StringUtils.isNotBlank(msgType) && "event".equalsIgnoreCase(msgType)){
                //微信事件处理，事件种类太多，eventKey命名怪异，暂时还没想到 好一点的通用处理方法
                dispatcherEventHandler.handle(dom4jHelper);
            }else{
                //微信消息处理，从 servlet配置的处理handler中 获取对应消息的处理Handel，
                MessageHandler handler = messageHandleMap.get(msgType);
                if(handler != null){
                    //根据微信传过来的xml 生成对应的接入消息bean
                    BaseReqMsg reqMsg = WeiXinUtils.buildReqMsg(msgType,dom4jHelper,prifxReqMsgBean);
                    //调用对应的消息处理handler生成 回复消息bean
                    resutlMsg = handler.handle(reqMsg);
                }
            }
            if(resutlMsg != null){
                resutlMsg.setFromUserName(toUserName);
                resutlMsg.setToUserName(fromUserName);
                writer.write(resutlMsg.toXml());
            }else{//不做处理的消息/事件要及时返回空字符串，或者SUCCESS，以免微信等待
                writer.write("");
            }
        }catch(Exception e){
            logger.error("微信处理消息出错");
            e.printStackTrace();
            writer.write("");
        }finally {
            writer.flush();
            writer.close();
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (isLegal(req)) {
            PrintWriter pw = resp.getWriter();
            try {
                pw.write(req.getParameter("echostr"));
            } catch (Exception e) {
                logger.error("绑定服务器异常", e);
            }finally {
                pw.flush();
                pw.close();
            }
        }
    }

    protected boolean isLegal(HttpServletRequest request) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        return SignUtil.checkSignature(wxConfig.getToken(), signature, timestamp, nonce);
    }




}
